package com.base.core.image;

import cn.hutool.core.util.ObjectUtil;
import com.base.core.lang.StringUtils;
import com.base.core.io.FileUtils;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;
import net.coobird.thumbnailator.geometry.Positions;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 图片处理工具类
 *
 * @author biao
 * @version 2018年12月31日
 */
public class ImageUtils {

    /**
     * 缩略图生成，处理一些较大的图片，防止占用太多的网络资源
     * 保存到本地
     *
     * @throws IOException
     */
    public static void thumbnails(File imageFile, int maxWidth, int maxHeight, String outputFormat) throws IOException {
        if (imageFile == null || !imageFile.exists() || (maxWidth <= 0 && maxHeight <= 0)) {
            return;
        }
        // 只处理可以压缩的图片，如gif图片压缩后会出现黑色背景的情况
        String extension = FileUtils.getFileExtension(imageFile.getName());
        if (!StringUtils.inString(extension, "png", "jpg", "jpeg", "bmp", "ico")) {
            return;
        }
        try {
            BufferedImage bufferedImage = ImageIO.read(imageFile);
            Builder<BufferedImage> bilder = Thumbnails.of(bufferedImage);
            if (bufferedImage != null) {
                if (maxWidth > 0) {
                    if (bufferedImage.getWidth() <= maxWidth) {
                        bilder.width(bufferedImage.getWidth());
                    } else {
                        bilder.width(maxWidth);
                    }
                }
                if (maxHeight > 0) {
                    if (bufferedImage.getHeight() <= maxHeight) {
                        bilder.height(bufferedImage.getHeight());
                    } else {
                        bilder.height(maxHeight);
                    }
                }
                if (StringUtils.isNotBlank(outputFormat)) {
                    bilder.outputFormat(outputFormat);
                }
                bilder.toFile(imageFile);
            }
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * <p>Discription:[isImage,判断文件是否为图片]</p>
     * @param file
     * @return true 是 | false 否
     */
    public static final boolean isImage(File file){
        boolean flag = false;
        try
        {
            BufferedImage bufreader = ImageIO.read(file);
            int width = bufreader.getWidth();
            int height = bufreader.getHeight();
            flag = width != 0 && height != 0;
        }
        catch (IOException e)
        {
            flag = false;
        }catch (Exception e) {
            flag = false;
        }
        return flag;
    }

    /**
     * 获取远程图片
     * @param imgUrl
     * @return
     * @throws IOException
     */
    public static BufferedImage getBufferedImage(String imgUrl) throws IOException {
        URL url = null;
        InputStream is = null;
        BufferedImage img = null;
        try {
            url = new URL(imgUrl);
            is = url.openStream();
            img = ImageIO.read(is);
        } catch (MalformedURLException e) {
            throw e;
        } catch (IOException e) {
            throw e;
        } finally {

            try {
                is.close();
            } catch (IOException e) {
                throw e;
            }
        }
        return img;
    }

    /**
     * 获取远程图片
     * @param imgUrl
     * @return
     * @throws IOException
     */
    public static byte[] getByteImage(String imgUrl) throws IOException {
        URL url;
        InputStream is = null;
        BufferedImage img;
        try {
            url = new URL(imgUrl);
            is = url.openStream();
            img = ImageIO.read(is);
        } catch (MalformedURLException e) {
            throw e;
        } catch (IOException e) {
            throw e;
        } finally {

            try {
                is.close();
            } catch (IOException e) {
                throw e;
            }
        }
        return ((DataBufferByte) img.getData().getDataBuffer()).getData();
    }

    /**
     * 指定大小进行缩放
     * @param imgUrl
     * @param maxWidth
     * @param maxHeight
     * @return
     * @throws IOException
     */
    public static BufferedImage sizeFromUrl(String imgUrl, int maxWidth, int maxHeight) throws IOException {
        BufferedImage bufferedImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
        } catch (IOException e) {
            throw e;
        }
       return Thumbnails.of(bufferedImage)
                .size(maxWidth, maxHeight)
                .asBufferedImage();
    }

    /**
     * 指定大小进行缩放
     * @param imgUrl
     * @param maxWidth
     * @param maxHeight
     * @return
     * @throws IOException
     */
    public static byte[] byteSizeFromUrl(String imgUrl, int maxWidth, int maxHeight) throws IOException {
        BufferedImage bufferedImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
        } catch (IOException e) {
            throw e;
        }
        BufferedImage thumbnailsBufferedImage = Thumbnails.of(bufferedImage)
                .size(maxWidth, maxHeight)
                .asBufferedImage();
        return ((DataBufferByte) thumbnailsBufferedImage.getData().getDataBuffer()).getData();
    }

    /**
     * 指定大小进行缩放并添加水印
     * @param imgUrl
     * @param maxWidth
     * @param maxHeight
     * @return
     * @throws IOException
     */
    public static BufferedImage sizeWaterFromUrl(String imgUrl, int maxWidth, int maxHeight, String waterUrl) throws Exception {
        BufferedImage bufferedImage;
        BufferedImage waterBufferdImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the image not found");
            }
            waterBufferdImage = getBufferedImage(waterUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the water image not found");
            }
        } catch (IOException e) {
            throw e;
        }
        return Thumbnails.of(bufferedImage)
                .size(maxWidth, maxHeight)
                .watermark(Positions.BOTTOM_RIGHT, waterBufferdImage, 0.5f)
                .outputQuality(0.8f)
                .asBufferedImage();
    }

    /**
     * 指定大小进行缩放并添加水印
     * @param imgUrl
     * @param maxWidth
     * @param maxHeight
     * @return
     * @throws IOException
     */
    public static byte[] byteSizeWaterFromUrl(String imgUrl, int maxWidth, int maxHeight, String waterUrl) throws Exception {
        BufferedImage bufferedImage;
        BufferedImage waterBufferdImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the image not found");
            }
            waterBufferdImage = getBufferedImage(waterUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the water image not found");
            }
        } catch (IOException e) {
            throw e;
        }
        BufferedImage thumbnailsBufferedImage = Thumbnails.of(bufferedImage)
                .size(maxWidth, maxHeight)
                .watermark(Positions.BOTTOM_RIGHT, waterBufferdImage, 0.5f)
                .outputQuality(0.8f)
                .asBufferedImage();
        return ((DataBufferByte) thumbnailsBufferedImage.getData().getDataBuffer()).getData();
    }

    /**
     * 等比例缩放进行缩放
     * @param imgUrl
     * @return
     * @throws IOException
     */
    public static BufferedImage scaleFromUrl(String imgUrl, Double scale) throws IOException {
        BufferedImage bufferedImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
        } catch (IOException e) {
            throw e;
        }
        return Thumbnails.of(bufferedImage)
                .scale(scale)
                .asBufferedImage();
    }

    /**
     * 等比例缩放进行缩放
     * @param imgUrl
     * @return
     * @throws IOException
     */
    public static byte[] byteScaleFromUrl(String imgUrl, Double scale) throws IOException {
        BufferedImage bufferedImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
        } catch (IOException e) {
            throw e;
        }
        BufferedImage thumbnailsBufferedImage = Thumbnails.of(bufferedImage)
                .scale(scale)
                .asBufferedImage();
        return ((DataBufferByte) thumbnailsBufferedImage.getData().getDataBuffer()).getData();
    }

    /**
     * 等比例缩放进行缩放并加水印
     * @param imgUrl
     * @param waterUrl
     * @return
     * @throws IOException
     */
    public static BufferedImage scaleWaterFromUrl(String imgUrl, Double scale, String waterUrl) throws Exception {
        BufferedImage bufferedImage;
        BufferedImage waterBufferdImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the image not found");
            }
            waterBufferdImage = getBufferedImage(waterUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the water image not found");
            }
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }

        return Thumbnails.of(bufferedImage)
                .watermark(Positions.BOTTOM_RIGHT, waterBufferdImage, 0.5f)
                .outputQuality(0.8f)
                .scale(scale)
                .asBufferedImage();
    }

    /**
     * 等比例缩放进行缩放并加水印
     * @param imgUrl
     * @param waterUrl
     * @return
     * @throws IOException
     */
    public static byte[] byteScaleWaterFromUrl(String imgUrl, Double scale, String waterUrl) throws Exception {
        BufferedImage bufferedImage;
        BufferedImage waterBufferdImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the image not found");
            }
            waterBufferdImage = getBufferedImage(waterUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the water image not found");
            }
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }

        BufferedImage thumbnailsBufferedImage = Thumbnails.of(bufferedImage)
                .watermark(Positions.BOTTOM_RIGHT, waterBufferdImage, 0.5f)
                .outputQuality(0.8f)
                .scale(scale)
                .asBufferedImage();
        return ((DataBufferByte) thumbnailsBufferedImage.getData().getDataBuffer()).getData();
    }

    /**
     * 等比例裁剪图片
     * @param imgUrl
     * @param maxWidth 裁剪宽度
     * @param maxHeight 裁剪高度
     * @param scale 裁剪比例
     * @return
     * @throws Exception
     */
    public static BufferedImage cropFromUrl(String imgUrl, int maxWidth, int maxHeight, Double scale) throws Exception {
        BufferedImage bufferedImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the image not found");
            }
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }

        return Thumbnails.of(bufferedImage)
                .sourceRegion(Positions.CENTER, maxWidth, maxHeight)
                .scale(scale)
                .asBufferedImage();
    }

    /**
     * 等比例裁剪图片
     * @param imgUrl
     * @param maxWidth 裁剪宽度
     * @param maxHeight 裁剪高度
     * @param scale 裁剪比例
     * @return
     * @throws Exception
     */
    public static byte[] byteCropFromUrl(String imgUrl, int maxWidth, int maxHeight, Double scale) throws Exception {
        BufferedImage bufferedImage;
        try{
            bufferedImage = getBufferedImage(imgUrl);
            if(ObjectUtil.isNull(bufferedImage)){
                throw new Exception("the image not found");
            }
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }

        BufferedImage thumbnailsBufferedImage = Thumbnails.of(bufferedImage)
                .sourceRegion(Positions.CENTER, maxWidth, maxHeight)
                .scale(scale)
                .asBufferedImage();
        return ((DataBufferByte) thumbnailsBufferedImage.getData().getDataBuffer()).getData();
    }
    /**
     * 将BufferedImage转换为InputStream
     * @param image
     * @return
     */
    public static InputStream bufferedImageToInputStream(BufferedImage image, String format) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {

            ImageIO.write(image, format, os);
            InputStream input = new ByteArrayInputStream(os.toByteArray());
            return input;
        } catch (IOException e) {
            throw e;
        }
    }

    public static byte[] bufferedImageToByte(BufferedImage image){
        byte[] data = ((DataBufferByte) image.getData().getDataBuffer()).getData();
        return data;
    }



}
